﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using NeedsMoreNinja.EventManager;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using SunXNA.RainbowXNA;

namespace Darwin.Source.Components.World.Team
{
    enum Side
    {
        Darwin,
        Creationists
    }

    class CTeam : IEventListener<SunXNA.SStep>,IEventListener<SunXNA.SFillWorld>
    {
        private List<Entities.CEntity> m_minions;
        private List<Entities.CBuilding> m_buildings;
        private List<PotentialFeild.CPotentialFeildVector> m_vectorPotentialFeilds;

        private PotentialFeild.CPotentialFeildVector m_headquarters;

        private CEntityController m_controller;

        private float m_totalResources;

        private World world;

        private Side teamSide;

        public float CurrentResources
        {
            get
            {
                return m_totalResources;
            }

            set
            {
                m_totalResources = value;
            }
        }

        public List<Entities.CEntity> Minions
        {
            get
            {
                return m_minions;
            }
        }

        public CEntityController Controller
        {
            get
            {
                return m_controller;
            }
        }

        public CTeam( CEntityController controller, World world, Side teamSide )
        {
            m_minions = new List<Darwin.Source.Components.World.Entities.CEntity>();
            m_buildings = new List<Darwin.Source.Components.World.Entities.CBuilding>();
            m_vectorPotentialFeilds = new List<Darwin.Source.Components.World.PotentialFeild.CPotentialFeildVector>();

            m_headquarters = null;

            m_controller = controller;

            this.world = world;

            this.teamSide = teamSide;

            m_totalResources = 240.0f;

            CEventManager<SunXNA.SStep>.AddListener(this);
            CEventManager<SunXNA.SFillWorld>.AddListener(this);
        }

        public TType SpawnEntity<TType>(Vector3 v3Position) where TType : Entities.CEntity, new()
        {
                TType newMinion = new TType();
                newMinion.Position = v3Position;
                newMinion.teamSide = this.teamSide;

                m_minions.Add(newMinion);
                world.m_entityDictionary.Add(newMinion.m_UID, newMinion);
                return newMinion;
        }

        public PotentialFeild.CPotentialFeildVector AddPotentialFeild(PotentialFeild.FeildType type,
                                                                      Vector3 v3Position,
                                                                      float fRadius,
                                                                      float fPower)
        {
            PotentialFeild.CPotentialFeildVector newPF = new Darwin.Source.Components.World.PotentialFeild.CPotentialFeildVector(++Components.World.World.m_UniversalID);
            newPF.Type = type;
            newPF.Position = v3Position;
            newPF.Radius = fRadius;
            newPF.Power = fPower;

            m_vectorPotentialFeilds.Add(newPF);
            if (m_headquarters == null && type == Darwin.Source.Components.World.PotentialFeild.FeildType.Home )
                m_headquarters = newPF;

            return newPF;
        }

        public TType SpawnBuilding<TType>(Vector3 v3Position) where TType : Entities.CBuilding, new()
        {
            if (m_totalResources > 200)
            {
                if (world.canCreateHere(v3Position))
                {
                    TType newBuilding = new TType();
                    newBuilding.Initialise(world.m_LoadedModels[0]);
                    v3Position.Y += 1;
                    newBuilding.Position = v3Position;
                    newBuilding.teamSide = this.teamSide;

                    m_buildings.Add(newBuilding);
                    world.m_buildingDictionary.Add(newBuilding.m_UID, newBuilding);

                    m_totalResources -= 200;
                    return newBuilding;
                }
            }
            return null;
        }

        void IEventListener<SunXNA.SStep>.Handle(SunXNA.SStep e)
        {
            //Texture2D image = world.m_potentialFeild.Texture;
            //Vector4[] worldFeildData = new Vector4[image.Width * image.Height];
            //image.GetData<Vector4>(worldFeildData);

            foreach (Entities.CEntity entity in m_minions)
            {
                entity.DoUpdate(e.gameTime, world, m_vectorPotentialFeilds, null);
            }

            foreach (Entities.CBuilding building in m_buildings)
            {
                building.DoUpdate(e.gameTime, world);
            }

            m_controller.Step(this, e.gameTime);
        }

        void IEventListener<SunXNA.SFillWorld>.Handle(SunXNA.SFillWorld e)
        {
            m_controller.Draw(this);
            List<Entities.CEntity> died_entities = new List<Entities.CEntity>();

            foreach (Entities.CEntity entity in m_minions)
            {
                // Check if we have to remove this entity
                if (entity.EntityState == Darwin.Source.Components.World.Entities.eEntityState._DEAD)
                {
                    died_entities.Add(entity);
                }
                else
                    entity.DoRender();
            }

            foreach (Entities.CEntity it_entities in died_entities)
            {
                m_minions.Remove(it_entities);
                world.m_entityDictionary.Remove(it_entities.m_UID);
            }
            died_entities.Clear();

            foreach (Entities.CBuilding building in m_buildings)
            {
                building.DoRender();
            }

            foreach (PotentialFeild.CPotentialFeildVector pf in m_vectorPotentialFeilds)
            {
                pf.Draw();
            }
        }

        public void Draw2D()
        {
            m_controller.Draw2D(this);
        }

        public PotentialFeild.CPotentialFeildVector getHeadQuaters()
        {
            return m_headquarters;
        }
    }
}
